/**
 * 支付宝工具包
 * 请勿修改此处代码，因为插件更新后此处代码会被覆盖。
 * 作者：VK
 */
const crypto = require("crypto");

var alipay = {};

var ALIPAY_ALGORITHM_MAPPING = {
  RSA: 'RSA-SHA1',
  RSA2: 'RSA-SHA256'
};

/**
 * 签名
 * @param {String} method 方法名
 * @param {Object} params 参数
 * @param {Object} config 配置
 */
alipay.sign = function(method, params, config) {
  let signParams = Object.assign({
    method,
    app_id: config.appId,
    charset: config.charset || "utf-8",
    version: config.version || "1.0",
    sign_type: config.signType || "RSA2",
  }, params);
  if (config.appCertSn && config.alipayRootCertSn) {
    signParams = Object.assign({
      app_cert_sn: config.appCertSn,
      alipay_root_cert_sn: config.alipayRootCertSn,
    }, signParams);
  }
  const bizContent = params.bizContent || params.biz_content;
  if (bizContent) {
    signParams.biz_content = JSON.stringify(bizContent);
  }
  // 排序
  const decamelizeParams = alipay.sortObj(signParams);
  // 拼接url参数
  let signStr = alipay.objectToUrl(decamelizeParams);

  let keyType = config.keyType || 'PKCS8';
  const privateKeyType = keyType === 'PKCS8' ? 'PRIVATE KEY' : 'RSA PRIVATE KEY'
  let privateKey = alipay.formatKey(config.privateKey, privateKeyType);
  // 计算签名
  const sign = crypto.createSign(ALIPAY_ALGORITHM_MAPPING[signParams.sign_type])
    .update(signStr, 'utf8').sign(privateKey, 'base64');
  return Object.assign(decamelizeParams, { sign });
};
/**
 * 格式化请求 url（按规范把某些固定的参数放入 url）
 * @param {Object} params 参数
 * @param {String} url 请求地址
 */
alipay.formatUrl = function(params, url = "https://openapi.alipay.com/gateway.do") {
  let requestUrl = url;
  // 需要放在 url 中的参数列表
  const urlArgs = [
    'app_id', 'method', 'format', 'charset',
    'sign_type', 'sign', 'timestamp', 'version',
    'notify_url', 'return_url', 'auth_token', 'app_auth_token',
    'ws_service_url',
  ];
  for (const key in params) {
    if (urlArgs.indexOf(key) > -1) {
      const val = encodeURIComponent(params[key]);
      requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?'}${key}=${val}`;
      // 删除 postData 中对应的数据
      delete params[key];
    }
  }
  return { execParams: params, url: requestUrl };
};

/**
 * 对象属性排序
 * @param {Object} obj
 */
alipay.sortObj = function(obj) {
  let sortArry = new Array;
  let keysArr = Object.keys(obj).sort();
  let sortObj = {};
  for (let i in keysArr) {
    sortObj[keysArr[i]] = (obj[keysArr[i]]);
  }
  return sortObj;
};
/**
 * 对象转url参数
 * @param {Object} obj
 */
alipay.objectToUrl = function(obj) {
  let str = "";
  for (let key in obj) {
    if (obj[key]) {
      str += `&${key}=${obj[key]}`;
    }
  }
  if (str) str = str.substring(1);
  return str;
};
/**
 * 格式化证书key
 * @param {String} key 密钥串
 * @param {String} type 密钥类型
 */
alipay.formatKey = function(key, type) {
  return `-----BEGIN ${type}-----\n${key}\n-----END ${type}-----`
};


module.exports = alipay;
